package com.seedog.mq.server;

import java.io.Serializable;
import java.util.Objects;

/**
 * 服务器配置类，用于配置SeeDog消息队列服务器的各种参数
 */
public class ServerConfig implements Serializable {
    private static final long serialVersionUID = 1L;
    
    // 默认配置参数
    private static final String DEFAULT_HOST = "localhost";
    private static final int DEFAULT_PORT = 7777;
    private static final boolean DEFAULT_DISTRIBUTED_MODE = false;
    private static final int DEFAULT_THREAD_POOL_SIZE = 20;
    private static final long DEFAULT_HEARTBEAT_INTERVAL = 5000; // 5秒
    private static final long DEFAULT_HEARTBEAT_TIMEOUT = 30000; // 30秒
    private static final long DEFAULT_ELECTION_TIMEOUT = 60000; // 60秒
    private static final int DEFAULT_REPLICATION_FACTOR = 2;
    private static final String DEFAULT_DATA_DIR = "./data";
    
    // 配置参数
    private String nodeHost = DEFAULT_HOST;
    private int nodePort = DEFAULT_PORT;
    private boolean distributedMode = DEFAULT_DISTRIBUTED_MODE;
    private int threadPoolSize = DEFAULT_THREAD_POOL_SIZE;
    private long heartbeatInterval = DEFAULT_HEARTBEAT_INTERVAL;
    private long heartbeatTimeout = DEFAULT_HEARTBEAT_TIMEOUT;
    private long electionTimeout = DEFAULT_ELECTION_TIMEOUT;
    private int replicationFactor = DEFAULT_REPLICATION_FACTOR;
    private String dataDir = DEFAULT_DATA_DIR;
    
    /**
     * 获取默认配置实例
     * @return 默认配置实例
     */
    public static ServerConfig getDefault() {
        return new ServerConfig();
    }
    
    /**
     * 获取节点主机名
     * @return 节点主机名
     */
    public String getNodeHost() {
        return nodeHost;
    }
    
    /**
     * 设置节点主机名
     * @param nodeHost 节点主机名
     */
    public void setNodeHost(String nodeHost) {
        if (nodeHost != null && !nodeHost.isEmpty()) {
            this.nodeHost = nodeHost;
        }
    }
    
    /**
     * 获取节点端口号
     * @return 节点端口号
     */
    public int getNodePort() {
        return nodePort;
    }
    
    /**
     * 设置节点端口号
     * @param nodePort 节点端口号
     */
    public void setNodePort(int nodePort) {
        if (nodePort > 0 && nodePort <= 65535) {
            this.nodePort = nodePort;
        }
    }
    
    /**
     * 获取是否启用分布式模式
     * @return 是否启用分布式模式
     */
    public boolean isDistributedMode() {
        return distributedMode;
    }
    
    /**
     * 设置是否启用分布式模式
     * @param distributedMode 是否启用分布式模式
     */
    public void setDistributedMode(boolean distributedMode) {
        this.distributedMode = distributedMode;
    }
    
    /**
     * 获取线程池大小
     * @return 线程池大小
     */
    public int getThreadPoolSize() {
        return threadPoolSize;
    }
    
    /**
     * 设置线程池大小
     * @param threadPoolSize 线程池大小
     */
    public void setThreadPoolSize(int threadPoolSize) {
        if (threadPoolSize > 0) {
            this.threadPoolSize = threadPoolSize;
        }
    }
    
    /**
     * 获取心跳间隔（毫秒）
     * @return 心跳间隔
     */
    public long getHeartbeatInterval() {
        return heartbeatInterval;
    }
    
    /**
     * 设置心跳间隔（毫秒）
     * @param heartbeatInterval 心跳间隔
     */
    public void setHeartbeatInterval(long heartbeatInterval) {
        if (heartbeatInterval > 0) {
            this.heartbeatInterval = heartbeatInterval;
        }
    }
    
    /**
     * 获取心跳超时时间（毫秒）
     * @return 心跳超时时间
     */
    public long getHeartbeatTimeout() {
        return heartbeatTimeout;
    }
    
    /**
     * 设置心跳超时时间（毫秒）
     * @param heartbeatTimeout 心跳超时时间
     */
    public void setHeartbeatTimeout(long heartbeatTimeout) {
        if (heartbeatTimeout > 0) {
            this.heartbeatTimeout = heartbeatTimeout;
        }
    }
    
    /**
     * 获取选举超时时间（毫秒）
     * @return 选举超时时间
     */
    public long getElectionTimeout() {
        return electionTimeout;
    }
    
    /**
     * 设置选举超时时间（毫秒）
     * @param electionTimeout 选举超时时间
     */
    public void setElectionTimeout(long electionTimeout) {
        if (electionTimeout > 0) {
            this.electionTimeout = electionTimeout;
        }
    }
    
    /**
     * 获取复制因子
     * @return 复制因子
     */
    public int getReplicationFactor() {
        return replicationFactor;
    }
    
    /**
     * 设置复制因子
     * @param replicationFactor 复制因子
     */
    public void setReplicationFactor(int replicationFactor) {
        if (replicationFactor > 0) {
            this.replicationFactor = replicationFactor;
        }
    }
    
    /**
     * 获取数据目录
     * @return 数据目录
     */
    public String getDataDir() {
        return dataDir;
    }
    
    /**
     * 设置数据目录
     * @param dataDir 数据目录
     */
    public void setDataDir(String dataDir) {
        if (dataDir != null && !dataDir.isEmpty()) {
            this.dataDir = dataDir;
        }
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ServerConfig that = (ServerConfig) o;
        return nodePort == that.nodePort &&
                distributedMode == that.distributedMode &&
                threadPoolSize == that.threadPoolSize &&
                heartbeatInterval == that.heartbeatInterval &&
                heartbeatTimeout == that.heartbeatTimeout &&
                electionTimeout == that.electionTimeout &&
                replicationFactor == that.replicationFactor &&
                Objects.equals(nodeHost, that.nodeHost) &&
                Objects.equals(dataDir, that.dataDir);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(nodeHost, nodePort, distributedMode, threadPoolSize,
                heartbeatInterval, heartbeatTimeout, electionTimeout,
                replicationFactor, dataDir);
    }
    
    @Override
    public String toString() {
        return "ServerConfig{" +
                "nodeHost='" + nodeHost + '\'' +
                ", nodePort=" + nodePort +
                ", distributedMode=" + distributedMode +
                ", threadPoolSize=" + threadPoolSize +
                ", heartbeatInterval=" + heartbeatInterval +
                ", heartbeatTimeout=" + heartbeatTimeout +
                ", electionTimeout=" + electionTimeout +
                ", replicationFactor=" + replicationFactor +
                ", dataDir='" + dataDir + '\'' +
                '}';
    }
}